<template>
  <el-dialog
    :ref="changeRef"
    class="z-dialog"
    :close-on-click-modal="true"
    :fullscreen="isFullscreen"
    :width="width"
    destroy-on-close
    lock-scroll
    draggable
    :show-close="false"
    align-center
    v-bind="getBindValue"
    @close="closeHandler"
    @closed="closedHandler"
  >
    <template #header="{ close }">
      <div class="header-content">
        <slot name="title">
          {{ title }}
        </slot>
        <div class="icon-container">
          <z-icon
            v-if="fullscreen"
            class="full-icon"
            :icon="isFullscreen ? 'radix-icons:exit-full-screen' : 'radix-icons:enter-full-screen'"
            :size="18"
            @click="toggleFull"
          />
          <z-icon icon="ep:close" class="close-icon" :size="18" @click.stop="close" />
        </div>
      </div>
    </template>

    <el-scrollbar v-if="scroll" :style="dialogStyle">
      <slot></slot>
    </el-scrollbar>
    <slot v-else></slot>
    <template v-if="slots.footer" #footer>
      <div :style="{ 'pointer-events': closing ? 'none' : 'auto' }">
        <slot name="footer"></slot>
      </div>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { isNumber } from '@/utils/is'
import type { ZDialogInstance, ZDialogProps } from '../types'

defineOptions({ name: 'ZDialog', inheritAttrs: false })

const props = withDefaults(defineProps<ZDialogProps>(), {
  title: 'dialog',
  fullscreen: true,
  width: '40%',
  scroll: false, // 是否开启滚动条。如果是的话，按照 maxHeight 设置最大高度
  maxHeight: '400px'
})

const slots = useSlots()
const vm = getCurrentInstance()
const isFullscreen = ref<boolean>(false) // 是否全屏
const dialogHeight = ref<string | number>(
  isNumber(props.maxHeight) ? `${props.maxHeight}px` : props.maxHeight
) // 格式化高度
const dialogStyle = computed(() => {
  return {
    height: unref(dialogHeight)
  }
})
const closing = ref<boolean>(false)
const getBindValue = computed(() => {
  const delArr: string[] = ['fullscreen', 'title', 'maxHeight']
  const attrs = useAttrs()
  const obj = { ...attrs }
  Object.assign(obj, props)
  for (const key in obj) {
    if (delArr.indexOf(key) !== -1) {
      delete obj[key]
    }
  }
  return obj
})

const toggleFull = () => {
  isFullscreen.value = !unref(isFullscreen)
}

const closeHandler = () => {
  closing.value = true
}

const closedHandler = () => {
  closing.value = false
}

const changeRef = (DialogInstance: Record<string, any> | null) => {
  if (vm) {
    vm.exposeProxy = vm.exposed = Object.assign(
      DialogInstance || {},
      {} // 这里写暴露的方法
    ) as ZDialogInstance
  }
}

defineExpose((vm?.exposeProxy || {}) as ZDialogInstance)
</script>

<style lang="scss">
.z-dialog {
  .icon-container {
    height: fit-content;
    position: absolute;
    right: 16px;
    top: 16px;
    display: flex;
    gap: 10px;

    .full-icon {
      cursor: pointer;

      @include useTheme {
        color: getStyle(--z-color-info);

        &:hover {
          color: getStyle(--z-color-primary);
        }
      }
    }

    .close-icon {
      cursor: pointer;

      @include useTheme {
        color: getStyle(--z-color-info);

        &:hover {
          color: getStyle(--z-color-primary);
        }
      }
    }
  }
}

.el-dialog {
  &__header {
    height: 54px;
    @include useTheme {
      border-bottom: 1px solid getStyle(--z-color-info);
    }

    .header-content {
      height: 100%;
    }
  }

  &__body {
    padding: 16px 0;
  }

  &__footer {
    @include useTheme {
      border-bottom: 1px solid getStyle(--z-color-info);
    }
  }
}
</style>
